﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Controls.Primitives;
using Bixas.Tangibilis.Controls.Primitives;
using System.Windows.Media;
using System.Collections;

namespace Bixas.Tangibilis.Controls
{
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(ScatterViewItem))]
    [TemplatePart(Name = "PART_TouchThumb", Type = typeof(TouchThumb))]
    public class ScatterView : TouchListBox
    {
        private TranslateTransform _translateTransform = new TranslateTransform();
        private ScaleTransform _scaleTransform = new ScaleTransform();
        private RotateTransform _rotateTransform = new RotateTransform();
        private TouchThumb _Thumb;

        static ScatterView()
        {
            FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(ScatterView), new FrameworkPropertyMetadata(typeof(ScatterView)));
        }

        public ScatterView()
        {
            this.RenderTransformOrigin = new Point(0.5, 0.5);
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new ScatterViewItem();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return (item is ScatterViewItem);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this._Thumb = base.GetTemplateChild("PART_TouchThumb") as TouchThumb;
            this._Thumb.TouchRotateDelta += new TouchRotateDeltaEventHandler(_Thumb_TouchRotateDelta);
            this._Thumb.TouchScaleDelta += new TouchScaleDeltaEventHandler(_Thumb_TouchScaleDelta);
            this._Thumb.TouchDragDelta += new TouchDragDeltaEventHandler(_Thumb_TouchDragDelta);
      
        }

        public Panel ItemsHost { get { return Phydeaux.Utilities.Dynamic<ItemsControl>.Instance.Property<Panel>.Params.Getter.CreateDelegate("ItemsHost").Invoke(this, new object[] { }); } set { } }

        void _Thumb_TouchDragDelta(object sender, TouchDragDeltaEventArgs e)
        {
            this._translateTransform.X += e.HorizontalChange;
            this._translateTransform.Y += e.VerticalChange;
            this.UpdateTransform();
        }

        private void UpdateTransform()
        {
            TransformGroup group = new TransformGroup();
            group.Children.Add(_scaleTransform);
            group.Children.Add(_rotateTransform);
            group.Children.Add(_translateTransform);
            
            this.ItemsHost.RenderTransform = group;
        }

        void _Thumb_TouchScaleDelta(object sender, TouchScaleDeltaEventArgs e)
        {
            this._scaleTransform.ScaleX += e.ScaleFactor;
            this._scaleTransform.ScaleY += e.ScaleFactor;

        }

        void _Thumb_TouchRotateDelta(object sender, TouchRotateDeltaEventArgs e)
        {
            this._rotateTransform.Angle += e.Angle;

        }


        #region Attached Properties

        #region IsDraggable

        /// <summary>
        /// IsDraggable Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty IsDraggableProperty =
            DependencyProperty.RegisterAttached("IsDraggable", typeof(bool), typeof(ScatterView),
                new FrameworkPropertyMetadata((bool)true));

        /// <summary>
        /// Gets the IsDraggable property.  This dependency property 
        /// indicates if the control can be dragged.
        /// </summary>
        public static bool GetIsDraggable(DependencyObject d)
        {
            return (bool)d.GetValue(IsDraggableProperty);
        }

        /// <summary>
        /// Sets the IsDraggable property.  This dependency property 
        /// indicates if the control can be dragged.
        /// </summary>
        public static void SetIsDraggable(DependencyObject d, bool value)
        {
            d.SetValue(IsDraggableProperty, value);
        }

        #endregion

        #region IsScaleable

        /// <summary>
        /// IsScaleable Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty IsScaleableProperty =
            DependencyProperty.RegisterAttached("IsScaleable", typeof(bool), typeof(ScatterView),
                new FrameworkPropertyMetadata((bool)true));

        /// <summary>
        /// Gets the IsScaleable property.  This dependency property 
        /// indicates if the control can be scaled.
        /// </summary>
        public static bool GetIsScaleable(DependencyObject d)
        {
            return (bool)d.GetValue(IsScaleableProperty);
        }

        /// <summary>
        /// Sets the IsScaleable property.  This dependency property 
        /// indicates if the control can be scaled.
        /// </summary>
        public static void SetIsScaleable(DependencyObject d, bool value)
        {
            d.SetValue(IsScaleableProperty, value);
        }

        #endregion

        #region IsRotateable

        /// <summary>
        /// IsRotateable Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty IsRotateableProperty =
            DependencyProperty.RegisterAttached("IsRotateable", typeof(bool), typeof(ScatterView),
                new FrameworkPropertyMetadata((bool)true));

        /// <summary>
        /// Gets the IsRotateable property.  This dependency property 
        /// indicates if the control can be rotated.
        /// </summary>
        public static bool GetIsRotateable(DependencyObject d)
        {
            return (bool)d.GetValue(IsRotateableProperty);
        }

        /// <summary>
        /// Sets the IsRotateable property.  This dependency property 
        /// indicates if the control can be rotated.
        /// </summary>
        public static void SetIsRotateable(DependencyObject d, bool value)
        {
            d.SetValue(IsRotateableProperty, value);
        }

        #endregion

        #region StartingAngle

        /// <summary>
        /// StartingAngle Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty StartingAngleProperty =
            DependencyProperty.RegisterAttached("StartingAngle", typeof(int?), typeof(ScatterView),
                new FrameworkPropertyMetadata((int?)null));

        /// <summary>
        /// Gets the StartingAngle property.  This dependency property 
        /// indicates the starting angle for this control.
        /// </summary>
        public static int? GetStartingAngle(DependencyObject d)
        {
            return (int?)d.GetValue(StartingAngleProperty);
        }

        /// <summary>
        /// Sets the StartingAngle property.  This dependency property 
        /// indicates the starting angle for this control.
        /// </summary>
        public static void SetStartingAngle(DependencyObject d, int? value)
        {
            d.SetValue(StartingAngleProperty, value);
        }

        #endregion

        #endregion
    }
}
